﻿using DAL.Model;
using DAL.Model.Local;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;

namespace DAL.Class
{
    public class CouchRepository : ICouchRepository, IDisposable
    {
        WebRequest webRequest;
        JavaScriptSerializer jss;
        bool disposed = false;
        public string couchDbConnectionString { get; set; }
        public CouchRepository()
        {
            couchDbConnectionString = ConfigurationManager.AppSettings["CouchDbConnectionString"];
            jss = new JavaScriptSerializer();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }       

        public List<SunHotelsHotelEntities> GetAllRecordByCountry(string country, int take, int skip)
        {
            try
            {//skip=" + skip.ToString() + "&limit=" + take.ToString() + "&
                string query = couchDbConnectionString + "_design/countries/_view/ByCountry?reduce=false&startkey=%22" + country + "%22&endkey=%22" + country + "%22";
                webRequest = WebRequest.Create(query);
                webRequest.Method = "GET";
                string jsonResult = "";
                using (WebResponse response = webRequest.GetResponse())
                {
                    using (var streamReader = new StreamReader(response.GetResponseStream()))
                    {
                        jsonResult = streamReader.ReadToEnd();
                    }
                }
                RootObject hotels = jss.Deserialize<RootObject>(jsonResult);
                List<SunHotelsHotelEntities> result = new List<SunHotelsHotelEntities>();
                hotels.rows.ForEach(hotel =>
                {
                    result.Add(ToSunHotelItem(hotel.value));
                });
                return result;
            }
            catch
            {
                return null;
            }

        }

        public HotelsResult GetAllRecord(int take, int skip)
        {
            try
            {
                
                string query = couchDbConnectionString + "_design/byValue/_view/byValue?reduce=false&skip=" + skip.ToString() + "&limit=" + take.ToString();
                webRequest = WebRequest.Create(query);
                webRequest.Method = "GET";
                string jsonResult = "";
                using (WebResponse response = webRequest.GetResponse())
                {
                    using (var streamReader = new StreamReader(response.GetResponseStream()))
                    {
                        jsonResult = streamReader.ReadToEnd();
                    }
                }
                RootObject hotels = jss.Deserialize<RootObject>(jsonResult);
              
                if (!hotels.rows.Any())
                    return new HotelsResult(){HasError = true, Message= "Brak hoteli. Proszę spóbować jeszcze raz"};
                
                var result = new HotelsResult();
               
                hotels.rows.ForEach(hotel =>
                {
                    var hotelMap = AutoMapper.Mapper.DynamicMap<Value, HotelShortModel>(hotel.value);
                    hotelMap.Token = hotel.id;
                    result.Hotels.Add(hotelMap);
                });
                result.TotalCount = hotels.total_rows;
                return result;
            }
            catch
            {
                return new HotelsResult(){HasError = true, Message= "Brak hoteli. Proszę spóbować jeszcze raz"};
            }
        }

        public List<SunHotelsHotelEntities> GetAllRecordByCity(string city, int take, int skip)
        {
            try
            {
                string query = couchDbConnectionString + "_design/cities/_view/byCity?skip=" + skip.ToString() + "&limit=" + take.ToString() + "&reduce=false&startkey=%22" + city + "%22&endkey=%22" + city + "+%22";
                webRequest = WebRequest.Create(query);
                webRequest.Method = "GET";
                string jsonResult = "";
                using (WebResponse response = webRequest.GetResponse())
                {
                    using (var streamReader = new StreamReader(response.GetResponseStream()))
                    {
                        jsonResult = streamReader.ReadToEnd();
                    }
                }
                RootObject hotels = jss.Deserialize<RootObject>(jsonResult);
                List<SunHotelsHotelEntities> result = new List<SunHotelsHotelEntities>();
                hotels.rows.ForEach(hotel =>
                {
                    result.Add(ToSunHotelItem(hotel.value));
                });
                return result;
            }
            catch
            {
                return null;
            }
        }

        public HotelDetails GetRecordByToken(string token)
        {
            try
            {
                string query = couchDbConnectionString + token.Trim();
                webRequest = WebRequest.Create(query);
                webRequest.Method = "GET";
                string jsonResult = "";
                using (WebResponse response = webRequest.GetResponse())
                {
                    using (var streamReader = new StreamReader(response.GetResponseStream()))
                    {
                        jsonResult = streamReader.ReadToEnd();
                    }
                }
                HotelDetails resultItem = new HotelDetails();
                Value hotel = jss.Deserialize<Value>(jsonResult);
                if (hotel != null)
                {
                    resultItem.Hotel = AutoMapper.Mapper.DynamicMap<Value, HotelShortModel>(hotel);
                }
                else
                {
                    return new HotelDetails() { HasError = true, Message = "Hotel nie został znaleziony" };
                }
                return resultItem;
            }
            catch
            {
                return new HotelDetails() { HasError = true, Message = "Brak Hotelu. Proszę spóbować jeszcze raz" };
            }
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposed)
                return;

            if (disposing)
            {

            }
            disposed = true;
        }

        private SunHotelsHotelEntities ToSunHotelItem(dynamic ob)
        {
            SunHotelsHotelEntities resultItem = new SunHotelsHotelEntities();
            resultItem = new SunHotelsHotelEntities
            {
                City = ob.City.Trim(),
                AccomodationType = ob.AccomodationType.Trim(),
                AddressStreet = ob.AddressStreet.Trim(),
                Country = ob.Country.Trim(),
                Description = ob.Description.Trim(),
                Headline = ob.Headline.Trim(),
                Id = ob.Id,
                Latitude = ob.Latitude.Trim(),
                Longitude = ob.Longitude.Trim(),
                Name = ob.Name.Trim(),
                Phone = ob.Phone.Trim(),
                Place = ob.Place.Trim(),
                SunHotelId = ob.SunHotelId.Trim(),
                ZipCode = ob.ZipCode.Trim()
            };
            return resultItem;
        }
    }
}
